package com.yuecai.modules.yc_order.service.impl;

import com.yuecai.exception.BadRequestException;
import com.yuecai.modules.security.JwtUserDto;
import com.yuecai.modules.yc_cart.domain.YcCart;
import com.yuecai.modules.yc_cart.repository.YcCartRepository;
import com.yuecai.modules.yc_coupon.service.YcCouponService;
import com.yuecai.modules.yc_goods.domain.YcGoods;
import com.yuecai.modules.yc_goods.repository.YcGoodsRepository;
import com.yuecai.modules.yc_goods.vo.YcGoodsOrderVo;
import com.yuecai.modules.yc_goods_sku.domain.YcGoodsSku;
import com.yuecai.modules.yc_goods_sku.repository.YcGoodsSkuRepository;
import com.yuecai.modules.yc_order.domain.YcOrder;
import com.yuecai.modules.yc_order.repository.YcOrderRepository;
import com.yuecai.modules.yc_order.service.OrderService;
import com.yuecai.modules.yc_order.service.dto.OrderDto;
import com.yuecai.modules.yc_order.service.dto.SubmitOrderDto;
import com.yuecai.modules.yc_order.service.utils.CoupontUtils;
import com.yuecai.modules.yc_order.service.utils.MakeOrderNum;
import com.yuecai.modules.yc_order.service.utils.OrderUtils;
import com.yuecai.modules.yc_order.service.vo.OrderVo;
import com.yuecai.modules.yc_order_goods.domain.YcOrderGoods;
import com.yuecai.modules.yc_order_goods.repository.YcOrderGoodsRepository;
import com.yuecai.modules.yc_receiver_info.domain.YcReceiverInfo;
import com.yuecai.modules.yc_receiver_info.repository.YcReceiverInfoRepository;
import com.yuecai.modules.yc_user.service.dto.YcUserDto;
import com.yuecai.modules.yc_user_coupon.domain.YcUserCoupon;
import com.yuecai.modules.yc_user_coupon.repository.YcUserCouponRepository;
import com.yuecai.utils.SecurityUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;


@Service
public class ShoppingCartService implements OrderService {

    @Autowired
    private YcCartRepository ycCartRepository;
    @Autowired
    private YcGoodsRepository ycGoodsRepository;
    @Autowired
    private YcGoodsSkuRepository ycGoodsSkuRepository;
    @Autowired
    private OrderUtils orderUtils;
    @Autowired
    private YcReceiverInfoRepository receiverInfoRepository;
    @Autowired
    private YcOrderGoodsRepository ycOrderGoodsRepository;
    @Autowired
    private YcOrderRepository ycOrderRepository;
    @Autowired
    private YcCouponService ycCouponService;
    @Autowired
    private CoupontUtils coupontUtils;
    @Autowired
    private YcUserCouponRepository ycUserCouponRepository;


    @Override
    public ResponseEntity writeOrder(OrderDto dto) throws Exception {
        String currentUsername = SecurityUtils.getCurrentUsername();
        Long userId = Long.valueOf(currentUsername);
        List<Long> catIds = dto.getCatIds();
        Long currentUserId = SecurityUtils.getCurrentUserId();
        List<YcCart> ycCarts = ycCartRepository.findByUserIdAndIdIn(currentUserId, catIds);

        JwtUserDto currentUser = (JwtUserDto) SecurityUtils.getCurrentUser();
        YcUserDto user = currentUser.getUser();
        Integer level = user.getLevel();

        ArrayList<YcGoodsOrderVo> ycGoods = new ArrayList<>();

        if (CollectionUtils.isNotEmpty(ycCarts)){
            for (YcCart ycCart : ycCarts) {
                Long skuId = ycCart.getSkuId();
                Integer goodsNumber = ycCart.getGoodsNumber();
                Optional<YcGoodsSku> oSku = ycGoodsSkuRepository.findById(skuId);

                YcGoodsOrderVo vo = orderUtils.getPriviceByLevel(level,oSku,goodsNumber);
                ycGoods.add(vo);
            }
        }
        if(CollectionUtils.isNotEmpty(ycCarts)){
            Map<Long, List<YcGoodsOrderVo>> groupBy = ycGoods.stream().collect(Collectors.groupingBy(YcGoodsOrderVo::getSupplierId));
            Set<Long> longs = groupBy.keySet();
            BigDecimal decimal = new BigDecimal("0.00");
            for (Long aLong : longs) {
                List<YcGoodsOrderVo> list = groupBy.get(aLong);
                BigDecimal totalPrice = new BigDecimal("0.00");
                for (YcGoodsOrderVo vo : list) {
                    Integer count = vo.getCount();
                    BigDecimal sellPrice = vo.getSellPrice();
                    BigDecimal multiply = sellPrice.multiply(new BigDecimal(count));
                    totalPrice = totalPrice.add(multiply);
                }
                //TODO 计算订单优惠
                decimal = totalPrice.add(decimal);
            }
            ResponseEntity responseEntity = orderUtils.checkTotalPrice(decimal);
            if (responseEntity!=null){
                return responseEntity;
            }

            List<YcUserCoupon> coupont = coupontUtils.findCoupont(ycGoods, userId, decimal);

            OrderVo ovo = new OrderVo();
            YcReceiverInfo receiverInfo = receiverInfoRepository.findByUserIdAndDefaultSignTrue(currentUserId);
            ovo.setReceiverInfo(receiverInfo);
            ovo.setYcGoodsOrderVos(ycGoods);
            ovo.setTotalPrice(decimal);
            ovo.setCoupont(coupont);
            return ResponseEntity.ok(ovo);
        }
        throw null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity submitOrder(SubmitOrderDto dto) throws Exception {
        Long receiveId = dto.getReceiveId();
        List<Long> catIds = dto.getCatIds();
        Long userId = SecurityUtils.getCurrentUserId();
        Optional<YcReceiverInfo> byId = receiverInfoRepository.findById(receiveId);
        if (!byId.isPresent()){
            throw new Exception("收货地址不存在！");
        }
        JwtUserDto currentUser = (JwtUserDto) SecurityUtils.getCurrentUser();
        YcUserDto user = currentUser.getUser();
        Integer level = user.getLevel();
        List<YcCart> ycCarts = ycCartRepository.findByUserIdAndIdIn(userId, catIds);
        ArrayList<YcGoodsOrderVo> ycGoods = new ArrayList<>();

        ArrayList<YcGoodsOrderVo> failureGood  = new ArrayList<>();
        List<YcGoods> ycGood  = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(ycCarts)){
            for (YcCart ycCart : ycCarts) {
                Long skuId = ycCart.getSkuId();
                Integer goodsNumber = ycCart.getGoodsNumber();
                Optional<YcGoodsSku> oSku = ycGoodsSkuRepository.findById(skuId);
                try {
                    YcGoodsOrderVo vo = orderUtils.getPriviceByLevel(level, oSku,goodsNumber);
                    ycGoods.add(vo);
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
        if(CollectionUtils.isEmpty(ycCarts)){
            throw new BadRequestException("购物车不存在！");
        }
        BigDecimal total = BigDecimal.valueOf(0);
        Long couponId = dto.getCouponId();
        if (couponId!=null){
            for (YcGoodsOrderVo a : ycGoods) {
                if (a.getSpecialOffer()==1){//特价商品不参与优惠
                    continue;
                }
                Integer count = a.getCount();
                BigDecimal sellPrice = a.getSellPrice();
                BigDecimal multiply = sellPrice.multiply(new BigDecimal(count));
                total = multiply.add(total);
            }
        }
        int v = (int) (1 + Math.random() * (9));
        String father = MakeOrderNum.makeOrderNum()+""+v;
        Map<Long, List<YcGoodsOrderVo>> groupBy = ycGoods.stream().collect(Collectors.groupingBy(YcGoodsOrderVo::getSupplierId));
        Set<Long> longs = groupBy.keySet();
        List<YcOrderGoods> orderGoods = new ArrayList<>();
        List<YcOrder> orders = new ArrayList<>();
        HashMap<String, Object> map = new HashMap<>();
        BigDecimal payPrice = new BigDecimal("0.00");
        BigDecimal specialOffer = new BigDecimal("0.00");
        YcUserCoupon coupon = null;
        for (Long aLong : longs) {
            List<YcGoodsOrderVo> vos = groupBy.get(aLong);
            BigDecimal bigDecimal = new BigDecimal("0.00");
            String s = MakeOrderNum.makeOrderNum();//订单
            for (YcGoodsOrderVo vo : vos) {
                YcOrderGoods orderGood = orderUtils.getOrderGood(vo,s,vo.getCount());
                orderGoods.add(orderGood);

                BigDecimal sellPrice = vo.getSellPrice();
                BigDecimal multiply = sellPrice.multiply(new BigDecimal(vo.getCount()));
                bigDecimal = multiply.add(bigDecimal);

                if (vo.getSpecialOffer()==1){
                    specialOffer = specialOffer.add(bigDecimal);
                }
            }
            YcOrder ycOrder = new YcOrder();
            ycOrder.setOrderSn(s);
            ycOrder.setOrderStatus(0);
            ycOrder.setReceiverId(receiveId);
            ycOrder.setTotalPrice(bigDecimal);
            ycOrder.setUserId(userId);
            ycOrder.setRemarks(dto.getRemarks());
            ycOrder.setSupplierId(aLong);
            if (longs.size()>1){
                ycOrder.setFatherOrders(father);
                map.put("orderSn",father);
            }else {
                map.put("orderSn",s);
            }

            //优惠券计算
            if (couponId != null&&couponId>0){
                //            `discount_type` int NOT NULL COMMENT '优惠的类型，0为金额，1为折扣',
//            `discount` decimal(12,2) NOT NULL COMMENT '优惠',
                coupon = coupontUtils.isUse(couponId,vos,total);
                if (coupon!=null){
                    BigDecimal discountsPrice = BigDecimal.valueOf(0);
                    Integer discountType = coupon.getDiscountType();
                    BigDecimal discount = coupon.getDiscount();
                    if (discountType == 0){
                        discountsPrice = discount;
                        bigDecimal = bigDecimal.subtract(discount);
                    }else if (discountType == 1){
                        BigDecimal divide = bigDecimal.multiply(discount).divide(BigDecimal.valueOf(10), 2);
                        discountsPrice = bigDecimal.subtract(divide);
                        bigDecimal = divide;
                    }
                    ycOrder.setDiscountsPrice(discountsPrice);
                    ycOrder.setCouponId(couponId);
                    couponId = -10000L;
                }
            }

            ycOrder.setPayPrice(bigDecimal);
            payPrice = payPrice.add(bigDecimal);
            orders.add(ycOrder);
        }
        ResponseEntity responseEntity = orderUtils.checkTotalPrice(payPrice);
        if (responseEntity!=null){
            return responseEntity;
        }

        if (coupon!=null){
            coupon.setIsUse(1);
            ycUserCouponRepository.save(coupon);
        }
        orderGoods = orderUtils.submitOrderGiftGood(payPrice,specialOffer,orderGoods,orders.get(0).getOrderSn());
        map.put("payPrice",payPrice);
        ycOrderRepository.saveAll(orders);
        //主要是修改库存
        ycGoodsRepository.saveAll(ycGood);
        ycOrderGoodsRepository.saveAll(orderGoods);
        Set<Long> collect = ycCarts.stream().map(YcCart::getId).collect(Collectors.toSet());
        ycCartRepository.removeByIdIn(collect);
        try {
            ycCouponService.giveYcCoupon(payPrice,specialOffer,userId);

            ycCouponService.newUserFirstOrder(payPrice,specialOffer,userId,orders);
        }catch (Exception e){
            System.out.println("领取优惠券失败！");
            e.printStackTrace();
        }
        return ResponseEntity.ok(map);
    }

    public static void main(String[] args) {
        Long tt = -1000L;
        System.out.println(tt);
    }


    @Override
    public ResponseEntity showPrice(SubmitOrderDto dto) throws Exception {
        List<Long> catIds = dto.getCatIds();
        Long userId = SecurityUtils.getCurrentUserId();
        JwtUserDto currentUser = (JwtUserDto) SecurityUtils.getCurrentUser();
        YcUserDto user = currentUser.getUser();
        Integer level = user.getLevel();
        List<YcCart> ycCarts = ycCartRepository.findByUserIdAndIdIn(userId, catIds);
        ArrayList<YcGoodsOrderVo> ycGoods = new ArrayList<>();

        if (CollectionUtils.isNotEmpty(ycCarts)){
            for (YcCart ycCart : ycCarts) {
                Long skuId = ycCart.getSkuId();
                Integer goodsNumber = ycCart.getGoodsNumber();
                Optional<YcGoodsSku> oSku = ycGoodsSkuRepository.findById(skuId);
                YcGoodsOrderVo vo = orderUtils.getPriviceByLevel(level, oSku,goodsNumber);
                ycGoods.add(vo);
            }
        }
        if(CollectionUtils.isEmpty(ycCarts)){
            throw new BadRequestException("购物车不存在！");
        }
        BigDecimal total = BigDecimal.valueOf(0);
        Long couponId = dto.getCouponId();
        if (couponId!=null){
            for (YcGoodsOrderVo a : ycGoods) {
                if (a.getSpecialOffer()==1){
                    continue;
                }
                Integer count = a.getCount();
                BigDecimal sellPrice = a.getSellPrice();
                BigDecimal multiply = sellPrice.multiply(new BigDecimal(count));
                total = multiply.add(total);
            }
        }
        Map<Long, List<YcGoodsOrderVo>> groupBy = ycGoods.stream().collect(Collectors.groupingBy(YcGoodsOrderVo::getSupplierId));
        Set<Long> longs = groupBy.keySet();
        List<YcOrderGoods> orderGoods = new ArrayList<>();
        HashMap<String, Object> map = new HashMap<>();
        BigDecimal payPrice = new BigDecimal("0.00");
        YcUserCoupon coupon = null;
        for (Long aLong : longs) {
            List<YcGoodsOrderVo> vos = groupBy.get(aLong);
            BigDecimal bigDecimal = new BigDecimal("0.00");
            String s = MakeOrderNum.makeOrderNum();//订单
            for (YcGoodsOrderVo vo : vos) {
                YcOrderGoods orderGood = orderUtils.getOrderGood(vo,s,vo.getCount());
                orderGoods.add(orderGood);

                BigDecimal sellPrice = vo.getSellPrice();
                BigDecimal multiply = sellPrice.multiply(new BigDecimal(vo.getCount()));
                bigDecimal = multiply.add(bigDecimal);
            }
            //优惠券计算
            if (couponId != null&&couponId>0){
                coupon = coupontUtils.showIsUse(couponId,vos,total);
                if (coupon!=null){
                    BigDecimal discountsPrice = BigDecimal.valueOf(0);
                    Integer discountType = coupon.getDiscountType();
                    BigDecimal discount = coupon.getDiscount();
                    if (discountType == 0){
                        discountsPrice = discount;
                        bigDecimal = bigDecimal.subtract(discount);
                    }else if (discountType == 1){
                        BigDecimal divide = bigDecimal.multiply(discount).divide(BigDecimal.valueOf(10), 2);
                        discountsPrice = bigDecimal.subtract(divide);
                        bigDecimal = divide;
                    }
                    map.put("discountsPrice",discountsPrice);
                    couponId = -10000L;
                }
            }
            payPrice = payPrice.add(bigDecimal);
        }
        ResponseEntity responseEntity = orderUtils.checkTotalPrice(payPrice);
        if (responseEntity!=null){
            return responseEntity;
        }

        map.put("payPrice",payPrice);
        HashMap<String, Object> map1 = orderUtils.giftGoodVo(payPrice);
        if (map1!=null){
            map.putAll(map1);
        }
        return ResponseEntity.ok(map);
    }


}
